use std::hash::sip::SipHasher;
use std::io::{fs, File, UserRWX, BufferedReader};
-use core::{Package, Target};
+use core::{Package, Target, PathKind};
use util;
use util::hex::short_hash;
use util::{CargoResult, Fresh, Dirty, Freshness, internal, Require, profile};
let filename = filename(target);
let old_loc = old.join(filename.as_slice());
let new_loc = new.join(filename.as_slice());
- let doc = target.get_profile().is_doc();
+
+ // We want to use the package fingerprint if we're either a doc target or a
+ // path source. If we're a git/registry source, then the mtime of files may
+ // fluctuate, but they won't change so long as the source itself remains
+ // constant (which is the responsibility of the source)
+ let use_pkg = {
+ let doc = target.get_profile().is_doc();
+ let path = match pkg.get_summary().get_source_id().kind {
+ PathKind => true,
+ _ => false,
+ };
+ doc || !path
+ };
debug!("fingerprint at: {}", new_loc.display());
// First bit of the freshness calculation, whether the dep-info file
// indicates that the target is fresh.
let (old_dep_info, new_dep_info) = dep_info_loc(cx, pkg, target, kind);
- let are_files_fresh = doc || try!(calculate_target_fresh(pkg, &old_dep_info));
+ let are_files_fresh = use_pkg ||
+ try!(calculate_target_fresh(pkg, &old_dep_info));
// Second bit of the freshness calculation, whether rustc itself and the
// target are fresh.
- let rustc_fingerprint = if doc {
+ let rustc_fingerprint = if use_pkg {
mk_fingerprint(cx, &(target, try!(calculate_pkg_fingerprint(cx, pkg))))
} else {
mk_fingerprint(cx, target)
{compiling} foo v0.5.0 ({url})
", updating = UPDATING, compiling = COMPILING, url = p.url(), bar = p2.url())));
})
+
+test!(git_repo_changing_no_rebuild {
+ let bar = git_repo("bar", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "pub fn bar() -> int { 1 }")
+ }).assert();
+
+ // Lock p1 to the first rev in the git repo
+ let p1 = project("p1")
+ .file("Cargo.toml", format!(r#"
+ [project]
+ name = "p1"
+ version = "0.5.0"
+ authors = []
+ build = 'true'
+ [dependencies.bar]
+ git = '{}'
+ "#, bar.url()).as_slice())
+ .file("src/main.rs", "fn main() {}");
+ p1.build();
+ p1.root().move_into_the_past().assert();
+ assert_that(p1.process(cargo_dir().join("cargo")).arg("build"),
+ execs().with_stdout(format!("\
+{updating} git repository `{bar}`
+{compiling} bar v0.5.0 ({bar}#[..])
+{compiling} p1 v0.5.0 ({url})
+", updating = UPDATING, compiling = COMPILING, url = p1.url(), bar = bar.url())));
+
+ // Make a commit to lock p2 to a different rev
+ File::create(&bar.root().join("src/lib.rs")).write_str(r#"
+ pub fn bar() -> int { 2 }
+ "#).assert();
+ bar.process("git").args(["add", "."]).exec_with_output().assert();
+ bar.process("git").args(["commit", "-m", "test"]).exec_with_output()
+ .assert();
+
+ // Lock p2 to the second rev
+ let p2 = project("p2")
+ .file("Cargo.toml", format!(r#"
+ [project]
+ name = "p2"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ "#, bar.url()).as_slice())
+ .file("src/main.rs", "fn main() {}");
+ assert_that(p2.cargo_process("build"),
+ execs().with_stdout(format!("\
+{updating} git repository `{bar}`
+{compiling} bar v0.5.0 ({bar}#[..])
+{compiling} p2 v0.5.0 ({url})
+", updating = UPDATING, compiling = COMPILING, url = p2.url(), bar = bar.url())));
+
+ // And now for the real test! Make sure that p1 doesn't get rebuilt
+ // even though the git repo has changed.
+ assert_that(p1.process(cargo_dir().join("cargo")).arg("build"),
+ execs().with_stdout(""));
+})